The present invention relates in general to data processing systems and in particular to an isochronous pipelined processor with deterministic control.
The typical personal computer system in use today includes a central processing unit (CPU) and a dedicated graphics co-processor. The graphics co-processor generally includes a video display pipeline that scans out the pixel buffer and provides pixel data to the display device at a fixed rate (e.g., 80 frames per second). The pixel data may be provided to the pixel buffer in response to various operating system and/or application programs executing on the CPU. Typically, the CPU also executes a driver program via which other programs can send commands to the graphics co-processor to specify various attributes (state parameters) of the output image. Attributes that can be specified may include display resolution (pixel density); color resolution (number of colors); position, size, and/or content of an overlay image (e.g., a cursor or video overlay); and so on, all of which might be controlled by a user or by various programs executing on the CPU. State parameters are typically stored in one or more state registers in the co-processor, where they can be updated in response to commands received from the CPU and accessed by the co-processor to control generation of the output image.
In most systems, the CPU and graphics co-processor operate asynchronously. Typically, the graphics co-processor has an associated command buffer in which commands received from the CPU are queued until execution. The CPU generally issues an instruction to the co-processor by writing a command to the command buffer, then proceeds to its next task without waiting for the command to execute. In such designs, there is no guarantee that state commands (i.e., commands updating the state parameters of the output pipeline) will arrive at the co-processor at a time when it is “safe” to execute them, i.e., when changing the state will not create artifacts in the image. For example, changing the display resolution in mid-frame, generally makes the image look torn. Likewise, changing the position of a cursor or other image element in mid-frame can also lead to tearing. To avoid such artifacts, typical co-processors are designed to synchronize updates to the state registers with “blanking periods” (dead time) in the pipeline, e.g., between the last pixel of one frame and the first pixel of the next frame.
Synchronizing state updates with blanking intervals presents a number of challenges. First, the co-processor must be able to detect when a blanking interval occurs. This has traditionally been done by polling a register on the pixel data path to detect the blanking interval. Second, the co-processor must ensure that a complete, coherent set of state updates is committed before the blanking interval ends. If the display pipeline is short enough or the frame rate is low enough, an adequate blanking interval can be provided by speeding up the rate at which pixels are delivered to the pipeline during each frame to allow for more dead time between frames. The co-processor can simply wait for the last pixel of the old frame to clear the pipeline, then execute the state commands before the first pixel of the next frame enters the pipeline.
Over time, however, frame rates and display resolutions (i.e., pixels per frame) have both increased, display pipelines have become longer, the number of adjustable state parameters has increased. Consequently, pipeline dead time between frames has been reduced, while the number of state parameters that may need to be updated during that dead time has increased to the point where in some co-processors it is no longer satisfactory to simply wait for the blanking interval and then begin issuing state commands. To reduce the time needed to commit the state updates, some co-processors now include double-buffered state registers having “assembly” and “active” buffers. The co-processor can execute state commands as they are received (i.e., at any point during a frame) by updating the assembly buffer while the current frame is generated using the active buffer. When the blanking interval arrives, the content of the assembly buffer can quickly be copied to the active buffer for use in processing the next frame.
This arrangement allows a large number of state updates to be made in a short period, but it creates a race condition between updates to the assembly buffer and transfers from the assembly buffer to the active buffer. For example, if the blanking interval arrives while state commands are being executed to update the assembly buffer, it is impossible to predict or guarantee that the data will be transferred from the assembly buffer to the active buffer either before or after a particular update to the assembly buffer. Thus, it is not guaranteed that the state parameters transferred into the active buffers will include a complete and coherent set of values. In addition, the pipeline behavior is non-deterministic; executing the same set of instructions (with the same image data) multiple times may produce different results due to the race condition. A non-deterministic pipeline makes verification of the co-processor's operation difficult (because the correct behavior is unpredictable) and in some instances may also produce visible artifacts in displayed images.
The problem of race conditions is further complicated in co-processors where the display pipeline is longer than the blanking interval. In such cases, the pipeline cannot be completely emptied between frames because the first pixel of the new frame enters the pipeline before the last pixel of the previous frame exits. If the same state registers are used for the entire pipeline, some of the pixels may be processed using the wrong parameters. This problem has been addressed in some systems by duplicating the state registers at different points (stages) along the pipeline. Each stage is made to be shorter than the blanking interval, so that each stage is empty of pixels at some point between frames, and the state registers at each stage may be double buffered. In this arrangement, updates to the assembly buffer are propagated through the successive pipeline stages, and transfers from the assembly buffer to the active buffer at each stage is synchronized with the blanking period in that stage. Where a race condition exists, however, it is possible that, at one stage, a state command will execute before the transfer from the assembly buffer to the active buffer while at a later stage the reverse will happen. Thus, in addition to being non-deterministic, the state may also be internally inconsistent so that the same pixel is processed using post-update state parameters at one stage and pre-update state parameters at another stage, making visual artifacts even more likely.
It would therefore be desirable to provide a display pipeline in which state can be controlled in a deterministic manner.